home *** CD-ROM | disk | FTP | other *** search
-
- Title vid_ screen Routines by Jerry Joplin [70441,2627] CIS
- Page ,132
-
- Subttl Usage Notes and Segment Declarations
- COMMENT *
-
- The following routines are a set of direct video-memory access
- routines. They are much faster than BIOS functions, yet maintain full
- Microsoft Windows, DESQview, and Topview rules of __good_behaviour__.
- Programs written using these techniques are fully capable of running
- as a concurrently executing task in a well behaved window.
-
- These routines have been designed for the small and tiny memory models
- of TURBOC Vers 1.0 and the small memory model for MSC Vers 4.0 and 5.0
-
- *
-
- _TEXT segment byte public 'CODE'
- DGROUP group _DATA,_BSS
- assume cs:_TEXT,ds:DGROUP,ss:DGROUP
- _TEXT ends
- _DATA segment word public 'DATA'
- _DATA ends
- _BSS segment word public 'BSS'
- _BSS ends
-
- _TEXT segment byte public 'CODE'
-
- assume cs:_TEXT, ds:DGROUP, es:nothing, ss:DGROUP
-
-
- Page ,132
- Subttl Procedure declarations
-
- public _vid_puts ;Write string w/attr
- public _vid_putc ;Write character w/attr
- public _vid_readc ;Read char/attr
-
- public _vid_begin ;Begin a video update
- public _vid_update ;End a video update
- public _vid_buffc ;Write a char/attr in an update
-
- public _vid_memread ;Video memory block read
- public _vid_memwrite ;Video memory block write
-
- public _vid_clearbox ;Clear a window
- public _vid_scrollbox ;Scroll a window
- public _vid_drawbox ;Draw a box around a window
- public _vid_setbox ;Set a box character set
-
- public _vid_setpage ;Set the active video page
- public _vid_setmode ;Set the video mode
- public _vid_poscurs ;Position the cursor
-
-
- Screen equ 10h
-
-
- Page ,132
- Subttl Functions
-
- ;-------------------------------------------------------------------------
- ;Write a null terminated string directly to Video memory
- ; If a virtual screen buffer is detected then write the
- ; string to the buffer and update the real display.
- ; If no virtual screen is detected then blast the string
- ; directly to video memory without snow for the CGA.
- ;-------------------------------------------------------------------------
-
- StringOfs equ [bp+4]
- Row equ [bp+6]
- Col equ [bp+8]
- Attr equ [bp+10]
-
- _vid_puts proc near
-
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov dh,byte ptr Row ;Determine video address for
- mov dl,byte ptr Col ; the specified row and column
- call GetVideoAddr ; as Seg:Offs in ES:DI
-
- mov si,StringOfs ;Get the address of the string
- mov ah,Attr ; and video attribute
-
- mov bx,es
- cmp bx,0b000h ;Video segment = Monochrome?
- jz Mono_Puts ; yes, then this case is easy
-
- cmp bx,0b800h ;Video segment = Color?
- jnz Buff_Puts ; no, then must be a shadow
- ; buffer we are writing to
-
- ;
- ; Write string a Non-Monochrome video screen
- ; accomodating CGA tendancy to snow
- ;
-
- Puts_Next:
- lodsb ;Load character of string
- or al,al ;Is it end of the string?
- jz VS_Puts_Exit ; yes, then exit.
- mov bx,ax ;Save video word in BX
- mov dx,03dah ;Prepare to read 6845
- cli ; disable interrupts
- V_Retrace_Puts:
- in al,dx ; get 6845 status
- test al,1000b ;Vertical retrace bit set?
- jnz Write_Puts ; yes, then write it
- rcr al,1 ; no, wait till horizontal
- jc V_Retrace_Puts ; retrace bit set
- H_Retrace_Puts:
- in al,dx ;Get 6845 status again
- rcr al,1 ; wait for horizontal
- jnc H_Retrace_Puts ; retrace bit
- Write_Puts:
- mov ax,bx ;Restore screen word
- stosw ; and move it to the screen
- sti ;Allow interrupts
- jmp short Puts_Next ;Continue until null is hit
-
- ;
- ; Write string to a virtual screen buffer and
- ; update the real screen
- ;
-
-
- Buff_Puts:
- push di ;Save beginning buffer offset
- xor cx,cx ; use CX for character count
- BuffNext:
- lodsb ; load next char into AL
- or al,al ; is it the end of the string?
- jz BuffWriteExit ; yes, then update buffer.
- stosw ; else write it to screen
- inc cx ; and increment the char count
- jmp short BuffNext ; continue with next char
-
- BuffWriteExit:
- pop di ;Restore buffer offset
- mov ah,0ffh ; Update the video buffer
- int Screen ; with chars altered in CX
- jmp short VS_Puts_Exit ; and exit.
-
- ;
- ; Write string to a monochrome screen
- ;
-
-
- Mono_Puts:
- lodsb ;Load character into AL
- or al,al ; is it the end of the string?
- jz VS_Puts_Exit ; yes, then exit.
- stosw ; else write it to screen
- jmp short Mono_Puts ; continue till null.
-
-
- VS_Puts_Exit:
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_puts endp
-
-
- ;-------------------------------------------------------------------------
- ;Write a character directly to Video memory
- ; If a virtual screen buffer is detected then write the
- ; character to the buffer and update the real display.
- ; If no virtual screen is detected then write the character
- ; directly to video memory without snow for the CGA.
- ;-------------------------------------------------------------------------
-
- Char equ [bp+4]
- Row equ [bp+6]
- Col equ [bp+8]
- Attr equ [bp+10]
-
- _vid_putc proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov dh,byte ptr Row ;Determine video address for
- mov dl,byte ptr Col ; the specified row and column
- call GetVideoAddr ; as Seg:Offs in ES:DI
-
- mov al,Char ;Get the character and
- mov ah,Attr ; video attribute
-
- mov bx,es
- cmp bx,0b000h ;Video segment = Monochrome?
- jz Mono_Putc ; yes, then use mono routine
-
- cmp bx,0b800h ;Video segment = Color?
- jnz Buff_Putc ; no, then must be a shadow
- ; buffer we are writing to
-
- ;
- ; Write character to a Non-Monochrome video screen
- ; accomodating CGA tendancy to snow
- ;
-
- mov bx,ax ;Save video word in BX
- mov dx,03dah ;Prepare to read 6845
- cli ; disable interrupts
- V_Retrace_Putc:
- in al,dx ; get 6845 status
- test al,1000b ;Vertical retrace bit set?
- jnz Write_Putc ; yes, then write it
- rcr al,1 ; no, wait for horizonal
- jc V_Retrace_Putc ; retrace bit
- H_Retrace_Putc:
- in al,dx ;Get 6845 status again
- rcr al,1 ; wait for horizontal
- jnc H_Retrace_Putc ; retrace bit
- Write_Putc:
- mov ax,bx ;Restore screen word
- mov es:[di],ax ; and move it to the screen
- sti ;Allow interrupts
- jmp short VS_Putc_Exit ; and exit.
-
- ;
- ; Write a character to a virtual screen buffer and
- ; update the real screen
- ;
-
- Buff_Putc:
- mov es:[di],ax ;Write the char/attribute
- mov cx,1
- mov ah,0ffh ;Update the video buffers
- int Screen ; one character change
- jmp short VS_Putc_Exit ; and exit.
-
- ;
- ; Write a character to a monochrome screen
- ;
-
- Mono_Putc:
- mov es:[di],ax ;Write the char/attr to screen
-
-
- VS_Putc_Exit:
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_putc endp
-
- ;-------------------------------------------------------------------------
- ;Read a character/attribute directly from Video memory
- ; If a virtual screen buffer is detected then read the
- ; character from the virtual screen buffer.
- ; If no virtual screen is detected then read the character
- ; directly from video memory without snow for the CGA.
- ;-------------------------------------------------------------------------
-
- Row equ [bp+4]
- Col equ [bp+6]
-
- _vid_readc proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov dh,byte ptr Row ;Determine video address for
- mov dl,byte ptr Col ; the specified row and column
- call GetVideoAddr ; as Seg:Offs in ES:DI
-
-
- mov bx,es
- cmp bx,0b000h ;Video segment = Monochrome?
- jz Mono_Readc ; yes, then use mono routine
-
- cmp bx,0b800h ;Video segment = Color?
- jnz Buff_Readc ; no, then must be a shadow
- ; buffer we are reading from
-
- ;
- ; Read character from a Non-Monochrome video screen
- ; accomodating CGA tendancy to snow
- ;
-
- mov dx,03dah ;Prepare to read 6845
- cli ; disable interrupts
- V_Retrace_Readc:
- in al,dx ; get 6845 status
- test al,1000b ;Vertical retrace bit set?
- jnz Read_Readc ; yes, then write it
- rcr al,1 ; no, wait for horizontal
- jc V_Retrace_Readc ; retrace bit
- H_Retrace_Readc:
- in al,dx ;Get 6845 status again
- rcr al,1 ; wait for horizontal
- jnc H_Retrace_Readc ; retrace bit
- Read_Readc:
- mov ax,es:[di] ; read char/attr from screen
- sti ;Allow interrupts
- jmp short VS_Readc_Exit ; and exit.
-
-
- ;
- ; Read a character from a virtual screen buffer or
- ; a monochrome display
- ;
-
-
- Buff_Readc:
-
- Mono_Readc: ;Monochrome and Virtual display
- mov ax,es:[di] ; reads are simple memory transfers
-
-
- VS_Readc_Exit:
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_readc endp
-
-
- ;-------------------------------------------------------------------------
- ;Read a block of Video memory from a row and col into a save buffer
- ; If a virtual screen buffer is detected then read the
- ; block from the virtual screen buffer.
- ; If no virtual screen is detected then read the block
- ; directly from video memory without snow for the CGA.
- ;-------------------------------------------------------------------------
-
- SaveBuff equ [bp+4]
- Row equ [bp+6]
- Col equ [bp+8]
- Count equ [bp+10]
-
- _vid_memread proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
- push ds
-
- mov dh,byte ptr Row ;Determine video address for
- mov dl,byte ptr Col ; the specified row and column
- call GetVideoAddr ; as Seg:Offs in ES:DI
-
- mov si,di ;Screen will be Source for reads
- mov di,SaveBuff ; destination is the Savebuff
- mov ax,ds ; swap ES and DS
- mov bx,es ; saving video segment in BX
- mov ds,bx
- mov es,ax
-
- cmp bx,0b000h ;Video segment = Monochrome?
- jz Mono_MemRead ; yes, then use mono routine
-
- cmp bx,0b800h ;Video segment = Color?
- jnz Buff_MemRead ; no, then must be a shadow
- ; buffer we are reading from
-
- ;
- ; Read memory block from a Non-Monochrome video screen
- ; accomodating CGA tendancy to snow
- ;
-
- mov cx,Count
- Color_MemRead:
-
- mov dx,03dah ;Prepare to read 6845
- cli ; disable interrupts
- V_Retrace_MemRead:
- in al,dx ; get 6845 status
- test al,1000b ;Vertical retrace bit set?
- jnz Read_MemRead ; yes, then write it
- rcr al,1 ; no, wait for horizontal
- jc V_Retrace_MemRead ; retrace bit
- H_Retrace_MemRead:
- in al,dx ;Get 6845 status again
- rcr al,1 ; wait for horizontal
- jnc H_Retrace_MemRead ; retrace bit
- Read_MemRead:
- movsw ;Save this video char/attr
- loop Color_MemRead ; and continue with next word
- jmp short VS_MemRead_Exit ; until through
-
-
-
- ;
- ; Read memory block from a virtual screen buffer or
- ; a monochrome display
- ;
-
-
- Buff_MemRead:
-
- Mono_MemRead:
- mov cx,Count ;Monochrome and Virtual display
- rep movsw ; reads are simple memory transfers
-
- VS_MemRead_Exit:
-
- pop ds
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_memread endp
-
-
- ;-------------------------------------------------------------------------
- ;Write to a block of Video memory at a row and col from a buffer
- ; If a virtual screen buffer is detected then write to the
- ; virtual screen buffer and update the real screen.
- ; If no virtual screen is detected then write
- ; directly to video memory without snow for the CGA.
- ;-------------------------------------------------------------------------
-
- SaveBuff equ [bp+4]
- Row equ [bp+6]
- Col equ [bp+8]
- Count equ [bp+10]
-
- _vid_memwrite proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov dh,byte ptr Row ;Determine video address for
- mov dl,byte ptr Col ; the specified row and column
- call GetVideoAddr ; as Seg:Offs in ES:DI
-
- mov si,SaveBuff ;Source is the Savebuff
-
- mov bx,es
- cmp bx,0b000h ;Video segment = Monochrome?
- jz Mono_MemWrite ; yes, then use mono routine
-
- cmp bx,0b800h ;Video segment = Color?
- jnz Buff_MemWrite ; no, then must be a video buffer
-
- ;
- ; Write a memory block to a Non-Monochrome video screen
- ; accomodating CGA tendancy to snow
- ;
-
- mov cx,Count
- Color_MemWrite:
-
- mov dx,03dah ;Prepare to read 6845
- cli ; disable interrupts
- V_Retrace_MemWrite:
- in al,dx ; get 6845 status
- test al,1000b ;Vertical retrace bit set?
- jnz Read_MemWrite ; yes, then write it
- rcr al,1 ; no, wait for horizontal
- jc V_Retrace_MemWrite ; retrace bit
- H_Retrace_MemWrite:
- in al,dx ;Get 6845 status again
- rcr al,1 ; wait for horizontal
- jnc H_Retrace_MemWrite ; retrace bit
- Read_MemWrite:
- movsw ;Save this video char/attr
- loop Color_MemWrite ; and continue with next char
- jmp short VS_MemWrite_Exit ; until through
-
-
- ;
- ; Write a memory block to a virtual screen buffer and
- ; update the real screen
- ;
-
-
- Buff_MemWrite:
- push di ;Save beginning buffer offset
- mov cx,Count ; Load character count
- rep movsw ; store the char/attr's
- pop di ; restore buffer offset
- mov cx,Count ; use CX for character count
- mov ah,0ffh ; Update the video buffer
- int Screen ; with chars altered in CX
- jmp short VS_MemWrite_Exit ; and exit.
-
- ;
- ; Write a memory block to a monochrome display
- ;
-
-
- Mono_MemWrite:
- mov cx,Count ;Monochrome display writes
- rep movsw ; are simple memory transfers
-
- VS_MemWrite_Exit:
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_memwrite endp
-
-
- ;-------------------------------------------------------------------------
- ;Start a video screen update
- ;-------------------------------------------------------------------------
-
- _vid_begin proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov bx,0b000h ;Assume monochrome adapter
-
- mov ax,40h ;Determine Screen Segment
- mov es,ax ; address BIOS Data segment
- cmp byte ptr es:[49h],7 ; monochrome video mode?
- jz GotBeginSeg ; yes, screen Seg is ok
-
- mov bx,0b800h ; no, set Non-Monochrome
- ; segment address
- GotBeginSeg:
- mov es,bx ; ES:DI = assumed video addr
- xor di,di
-
- mov ah,0feh ;Get our process video address
- int Screen
-
- mov VideoSeg,es ;Save the video memory address
- mov VideoOfs,di ; for following buffer writes
-
- mov StartOfs,0ffffh ;Set the initial start offset to
- ; large value, any writes will
- ; be to an address below it
- mov EndOfs,di ;Set the initial end offset to
- ; start of video memory so any
- ; write will be at higher address
- ; above it
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_begin endp
-
-
- ;-------------------------------------------------------------------------
- ;End a video update
- ;-------------------------------------------------------------------------
-
- _vid_update proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov es,VideoSeg ;Retrieve the starting addr
- ; of the beginning of the
- mov di,StartOfs ; altered video memory
- cmp di,0ffffh ; If nothing has been altered
- jz VS_Update_Exit ; then theres nothing to update
-
- mov cx,EndOfs ;Calculate the number of
- sub cx,di ; *characters* changed
- shr cx,1 ; (EndOffs-StartOffs) / 2
- inc cx ; add 1 for round off
-
- mov ah,0ffh ;Update the video buffer
- int Screen ; with chars altered in CX
-
- VS_Update_Exit:
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_update endp
-
-
-
- ;-------------------------------------------------------------------------
- ;Buffer a character to the process virtual screen
- ;-------------------------------------------------------------------------
-
- Char equ [bp+4]
- Row equ [bp+6]
- Col equ [bp+8]
- Attr equ [bp+10]
-
- _vid_buffc proc near
-
- push bp
- mov bp,sp
-
- push di
- push si
-
- mov dh,byte ptr Row
- mov dl,byte ptr Col
- mov di,VideoOfs ;Use values saved in vs_begin
- mov es,VideoSeg ; as starting video address
-
- xor ax,ax ;Calculate screen offset
- mov al,dh ; load row into AX and BX
- mov bx,ax
- shl ax,1 ; avoid MUL instruction for
- shl ax,1 ; slower 8088 based systems
- shl ax,1 ; AX = row * 8
- shl bx,1 ; BX = row * 2
- add bx,ax ; BX = AX + BX = row * 10
- shl bx,1
- shl bx,1
- shl bx,1 ; BX = row * 80
- xor dh,dh
- add bx,dx ; BX = row * 80 + columns
- shl bx,1 ; account for attribute bytes
- add di,bx
-
- mov al,Char ;Place attr/char in AX
- mov ah,Attr
-
- mov bx,es
- cmp bx,0b000h ;Use Mono Character display?
- jz Mono_Buffc ; yes, then branch to it
-
- cmp bx,0b800h ;Use Color charcter display?
- jnz Buff_Buffc ; no, then must be a shadow
- ; buffer we are writing to
-
- mov bx,ax ;Save video word in BX
- mov dx,03dah ;Prepare to read 6845
- cli ; disable interrupts
- V_Retrace_Buffc:
- in al,dx ; get 6845 status
- test al,1000b ;Vertical retrace?
- jnz Write_Buffc ; yes, then write it
- rcr al,1 ; no, wait for end of
- jc V_Retrace_Buffc ; horizontal retrace
- H_Retrace_Buffc:
- in al,dx ;Get 6845 status again
- rcr al,1 ; wait for horizontal
- jnc H_Retrace_Buffc ; retrace
- Write_Buffc:
- mov ax,bx ;Restore screen word
- mov es:[di],ax ; and move it to the screen
- sti ;Allow interrupts
- jmp short VS_Buffc_Exit
-
-
-
- Buff_Buffc:
- cmp di,StartOfs ;See if this offset is
- jae Ofs_greater ; LESS than any previous
- mov StartOfs,di ; since last call to vs_begin
-
- Ofs_greater:
- cmp di,EndOfs ;See if this offset is
- jbe Mono_Buffc ; GREATER than any previous
- mov EndOfs,di ; since last call to vs_begin
-
- Mono_Buffc:
- mov es:[di],ax ; store the attr/char
-
- VS_Buffc_Exit:
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_buffc endp
-
-
-
- ;-------------------------------------------------------------------------
- ;Draw a box to the process virtual screen
- ;-------------------------------------------------------------------------
-
- TRow equ [bp+8]
- LCol equ [bp+10]
- BRow equ [bp+12]
- RCol equ [bp+14]
- Attr equ [bp+16]
- BorderType equ [bp+18]
- Next equ [bp-2]
-
- _vid_drawbox proc near
-
- push si
- push di ;Save register variables
- push bp
- mov bp,sp ; address call stack
- dec sp
- dec sp ; allocate 1 word pointer variable
-
-
- mov si,LCol ; SI used as column counter
- mov di,TRow ; DI used as row counter
-
- mov cx,BorderType ;Get the address of the
- lea bx,border0 ; box character set
- jcxz BoxIndexGot ; if set 0 then already got it
- GetBoxIndex:
- add bx,8 ; else add 8 till we got it
- loop GetBoxIndex
- BoxIndexGot:
- mov Next,bx ; save this address in Next
-
- ;The Top row of the Box
- call _vid_begin ; lies in a contigious block
- ; of screen memory so
- ; start a screen update
- DrawTopLeft:
- push Attr ;Draw the top left character
- push si ; using vid_buffc
- push di
- mov bx,Next
- push [bx]
- call _vid_buffc
- add sp,8
-
- inc word ptr Next ;Point Next to next box char
- DrawTopLine:
- inc si ;Move SI to next column
- cmp si,word ptr RCol ; hit the right side yet?
- jae DrawTopRight ; yes, then draw top right
-
- push Attr ;Draw chars of the top line
- push si ; using vid_buffc
- push di
- mov bx,word ptr Next
- push [bx]
- call _vid_buffc
- add sp,8
- jmp short DrawTopLine
-
-
- DrawTopRight:
- inc word ptr Next ;Point Next to next box char
-
- push Attr ;Draw the top right char
- push si ; using vid_buffc
- mov ax,di
- push ax
- mov bx,Next
- push [bx]
- call _vid_buffc
- add sp,8
-
- call _vid_update ;End this screen 'transaction'
-
-
-
- inc word ptr Next ;Point Next to next box char
- DrawRightLine:
- inc di ;Move DI next row
- cmp di,word ptr BRow ; hit the bottom yet?
- jae DrawBottomRight ; yes, then draw bottom right
-
- push Attr ;Draw the characters of the
- push si ; right side using vid_putc
- push di ; since vertical lines
- mov bx,Next ; do not lie in a contigious
- push [bx] ; block of screen memory
- call _vid_putc
- add sp,8
- jmp short DrawRightLine
-
-
- DrawBottomRight: ;The Bottom row of the Box
- call _vid_begin ; lies in a contigious block
- ; of screen memory so
- ; start a screen update
-
- inc word ptr Next ;Point Next to next box char
-
- push Attr ;Draw the bottom right
- push si ; character using vid_buffc
- push di
- mov bx,Next
- push [bx]
- call _vid_buffc
- add sp,8
-
- inc word ptr Next ;Point Next to next box char
- DrawBottomLine:
-
- dec si ;Move SI to next column
- cmp si,word ptr LCol ; hit the left side yet?
- jbe DrawBottomLeft ; yes, then draw bottom left
-
- push Attr ;Draw chars of the bottom
- push si ; line using vid_buffc
- push di
- mov bx,Next
- push [bx]
- call _vid_buffc
- add sp,8
- jmp short DrawBottomLine
-
-
- DrawBottomLeft:
- inc word ptr Next ;Point Next to next box char
-
- push Attr ;Draw the bottom left char
- push si ; using vid_buffc
- push di
- mov bx,Next
- push [bx]
- call _vid_buffc
- add sp,8
-
-
-
- call _vid_update ;End this screen 'transaction'
-
-
- inc word ptr Next ;Point Next to next box char
- DrawLeftLine:
- dec di ;Move up to next row
- cmp di,word ptr TRow ; hit top yet?
- jbe DrawBoxExit ; yes, then box is thru
-
- push Attr ;Draw the characters of the
- push si ; left side using vid_putc
- push di ; since vertical lines
- mov bx,Next ; do not lie in a contigious
- push [bx] ; block of screen memory
- call _vid_putc
- add sp,8
- jmp short DrawLeftLine
-
- DrawBoxExit:
- mov sp,bp
- pop bp
- pop di
- pop si
- ret
- _vid_drawbox endp
-
- ;-------------------------------------------------------------------------
- ;Set a box rendition set
- ;-------------------------------------------------------------------------
-
- BorderSet equ [bp+4]
- UpperLeft equ [bp+6]
- Top equ [bp+8]
- UpperRight equ [bp+10]
- Right equ [bp+12]
- LowerRight equ [bp+14]
- Bottom equ [bp+16]
- LowerLeft equ [bp+18]
- Left equ [bp+20]
-
- _vid_setbox proc near
-
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- push ds ;Extra segment = data segment
- pop es
-
- mov cx,BorderSet ;Get the address of the box
- lea di,border0 ; character set to establish
- jcxz BoxIndexSet ; if set 0 then already got it
- SetBoxIndex:
- add di,8 ; else add 8 till we hit it
- loop SetBoxIndex
- BoxIndexSet:
-
- lea si,UpperLeft ;Point Source index to new box set
- mov cx,8 ; contains 8 characters
- cld ; Lets be __forward__ shall we
-
- GetBoxChars: lodsw ;Get a word from stack
- stosb ; and save the low order byte
- loop GetBoxChars ; as a box character
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
- _vid_setbox endp
-
-
- ;-------------------------------------------------------------------------
- ;Clear a box on the video screen
- ; by invoking BIOS scroll window function
- ; specifying 0 lines to scroll
- ;-------------------------------------------------------------------------
-
- Urow equ [bp+4]
- Lcol equ [bp+6]
- Brow equ [bp+8]
- Rcol equ [bp+10]
- Attr equ [bp+12]
-
- _vid_clearbox proc near
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov ax,0600h ;Use BIOS scroll window up function
- ; AL = 0 to blank area
- jmp short BIOS_Scroll
-
- _vid_clearbox endp
-
-
- ;-------------------------------------------------------------------------
- ;Scroll a box on the video screen
- ; a specified direction and number of lines
- ; by invoking BIOS scroll window function
- ;-------------------------------------------------------------------------
-
- Urow equ [bp+4]
- Lcol equ [bp+6]
- Brow equ [bp+8]
- Rcol equ [bp+10]
- Attr equ [bp+12]
- Direction equ [bp+14]
- NumberOfLines equ [bp+16]
-
- _vid_scrollbox proc near
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
- ;Use BIOS scroll window up function
- mov ah,Direction ; valid directions are 0 and 1
- add ah,6 ; function 6 is up, 7 is down
- mov al,NumberOfLines ; AL holds number of scroll lines
-
- BIOS_Scroll:
- mov bh,byte ptr Attr ; BH holds video attribute
- mov ch,byte ptr Urow
- mov cl,byte ptr Lcol ; CH:CL = top left
- mov dh,byte ptr Brow ; DH:DL = bottom right
- mov dl,byte ptr Rcol
- int screen ; transfer to BIOS
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_scrollbox endp
-
-
-
- ;-------------------------------------------------------------------------
- ;Set the active video page
- ;-------------------------------------------------------------------------
-
- Vpage equ [bp+4]
-
- _vid_setpage proc near
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov al,byte ptr Vpage ;Get specified page
- mov VideoPage,al ; save it to avoid overhead of
- ; get video page requests
-
- mov ah,5 ;Use BIOS set video page function
- int screen ; transfer to BIOS
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_setpage endp
-
- ;-------------------------------------------------------------------------
- ;Establish the video mode
- ;-------------------------------------------------------------------------
-
- Vmode equ [bp+4]
-
- _vid_setmode proc near
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov al,byte ptr Vmode ;Get specified mode
- xor ah,ah ;Use BIOS set video mode function
- int screen ; transfer to BIOS
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_setmode endp
-
- ;-------------------------------------------------------------------------
- ;Set the cursor to a position on the active video page
- ;-------------------------------------------------------------------------
-
- Row equ [bp+4]
- Col equ [bp+6]
-
-
- _vid_poscurs proc near
- push bp
- mov bp,sp ;Address call parameters and
- push di ; save register variables
- push si
-
- mov ah,2 ;Use BIOS set cursor pos function
- mov bh,VideoPage ; in the saved video page
- mov dh,byte ptr Row ; DH:DL holds position
- mov dl,byte ptr Col
- int screen ;Transfer to BIOS
-
- pop si
- pop di
- pop bp ;Restore registers
- ret ; and return
-
- _vid_poscurs endp
-
-
-
- ;-------------------------------------------------------------------------
- ;Retrieve the video buffer address
- ; On Entry:
- ; DX = row in DH, column in DL
- ; Returns
- ; ES:DI video buffer address
- ;-------------------------------------------------------------------------
-
- GetVideoAddr proc near
-
- mov bx,0b000h ;Assume monochrome adapter
-
- mov ax,40h ;Determine Screen Segment
- mov es,ax ; address BIOS Data segment
- cmp byte ptr es:[49h],7 ; monochrome video mode?
- jz GotScreenAddr ; yes, screen Seg is ok
-
- mov bx,0b800h ; no, set Non-Monochrome
- ; segment address
- GotScreenAddr:
- mov es,bx ; ES:DI =assumed video addr
- xor di,di
-
- mov ah,0feh ;Get our process video
- int Screen ; memory address
-
- xor ax,ax ;Calculate screen offset
- mov al,dh ; load row into AX and BX
- mov bx,ax
- shl ax,1 ; avoid MUL instruction for
- shl ax,1 ; slower 8088 based systems
- shl ax,1 ; AX = row * 8
- shl bx,1 ; BX = row * 2
- add bx,ax ; BX = AX + BX = row * 10
- shl bx,1
- shl bx,1
- shl bx,1 ; BX = row * 80
- xor dh,dh
- add bx,dx ; BX = row * 80 + columns
- shl bx,1 ; account for attribute bytes
-
- add di,bx ;Add the row and column offset
- ; to the video address offset
- ret ; and return
-
- GetVideoAddr endp
-
-
- _TEXT ends
-
- ;-------------------------------------------------------------------------
- ;vid_ routines data
- ;-------------------------------------------------------------------------
-
- _DATA segment
-
-
- StartOfs dw 0ffffh ;Starting offset in an update
- Endofs dw ? ;Ending offset in an update
- VideoOfs dw 0 ;Saved Offset and Segment pointer
- VideoSeg dw ? ; to the video screen in an update
-
- VideoPage db 0 ;Holds the current video page
-
- ;Box character sets, defaults:
- border0 db 8 dup (' ') ; 0 = spaces
- border1 db 218,196,191,179,217,196,192,179 ; 1 =single line border,
- border2 db 201,205,187,186,188,205,200,186 ; 2 =double line border.
- border3 db 8 dup (0)
- border4 db 8 dup (0)
- border5 db 8 dup (0) ; 3 - 7 should be set using
- border6 db 8 dup (0) ; vid_setbox before using
- border7 db 8 dup (0)
-
- _DATA ends
-
-
- end
-